package ua.tach.shortl.logic;

import ua.tach.shortl.Renderer;

import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.Mesh;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.math.Vector3;

public class Rail {
	public static final float BASERAILSIZE = 20.0f;
	public static final float CHECKINGSTEP = 2;

	public static Mesh[] mesh = { Renderer.toLoad[0].m, Renderer.toLoad[1].m };
	public static Texture[] texture = { Renderer.toLoad[0].tx, Renderer.toLoad[1].tx };
	protected Point shift;
	protected float rotation;
	protected float build; // for new rail marking

	protected Switch[] sw = { Switch.NULL, Switch.NULL };

	public Rail (Switch left, Switch right, Vector2 sh, float r) {
		sw[0] = left;
		sw[1] = right;
		shift = new Point(Math.round(sh.x+0.25f), Math.round(sh.y+0.25f));
		rotation = r;
	}

	public Rail (Point sh, float r, boolean paid) {
		sw[0] = sw[1] = Switch.NULL;
		shift = sh;
		rotation = r;
		build = 0.1f;
		cutTrees (paid);
	}

	public Rail() {
		sw[0] = sw[1] = Switch.NULL;
		build = 0.1f;
		shift = new Point();
	}

	public void cutTrees (boolean paid) {
		int money = 0;
		RailPosition rp = new RailPosition();
		rp.pos = getRailSize ();
		while (rp.pos > 0) {
			getCoordinate(rp);
			money += Country.cutTree(rp.renderCoord);
			rp.pos -= CHECKINGSTEP;
		}
		if (paid) Country.bank.getMoney(money);
	}

	public boolean swChange(Switch left, Switch right) {
		sw[0] = left;
		sw[1] = right;
		return false;
	}

	public int getRailDir (Switch s) {
		return 2;
	}

	public boolean checkColor (Vector3 col) {
		return false;
	}

	public void render (GL10 gl) {
		this.render(gl, 0);
	}

	public void render (GL10 gl, int index) {
		texture[index].bind();
		gl.glPushMatrix();
		gl.glTranslatef(shift.x, 0, shift.y);
		gl.glRotatef(rotation, 0, rotation, 0);
		gl.glColor4f(1, 1, 1, build);
		mesh[index].render(GL10.GL_TRIANGLES);
		gl.glPopMatrix();
	}

	public void move(Vector3 v) {
	}

	public Rail connectTo ( Point p) {
		return this;
	}

	public void tick() {
		if (build < 0.8f) {
			build += 0.04f;
			if (build > 0.75f) build = 1;
		}
	}

	public Point getSecond() {
		return new Point(0,0);
	}

	/*
	 *  For train moving:
	 *  Every rail have BASERAILSIZE fixed positions.
	 *  if position negative - wagon moves backward
	 */

	public float getRailSize () {
		return BASERAILSIZE;
	}

	public boolean isNeighbor (Rail r) {
		return r != this && (sw[0].isMine(r) || sw[1].isMine(r));
	}

	public boolean isCorrectPos(RailPosition p) {
		return !(p.pos<0 || p.pos>= BASERAILSIZE);
	}

	// Changes render coordinate
	public boolean getCoordinate(RailPosition pos) {
		return false;
	}

	public boolean isFreeWay(RailPosition p) {
		if ( isCorrectPos(p)) {
			return true;
		} else {
			Switch my = sw[(p.dir== p.train.movingDirection)?1:0];
			if(my.getRail() == this || my.sem.semType !=  1) {
				return my.getNext().checkRail();
			}
			return false;
		}
	}

	public boolean getNextRail(RailPosition pos) {
		boolean res = false;
		Switch my = sw[(pos.dir== pos.train.movingDirection)?1:0];

		if(my.getRail() == this || my.sem.semType !=  1) {
			Switch sss = my.getNext();
			pos.base = sss.getRail();
			if(pos.base==Rail.NULL || pos.base.build < 0.9f) {
				pos.base = this;
				res = true;
			} else {

				// Lock switches for whole train
				my.setLock(pos.train);
				sss.setLock(pos.train);

				if (pos.train.movingDirection) // sync to rail
					pos.pos = 0.01f;
				else
					pos.pos = pos.base.getRailSize()-0.01f;
				pos.dir = (sss.getRailDir() == pos.train.movingDirection);
			}
		} else {
			pos.base = this;
			res = true;
		}
		return res;
	}

	// Empty rail
	public static class NullRail extends Rail implements Null {
        private NullRail() {
            super(null, null, new Vector2(0,0), 0.0f);
        }

		@Override
		public void render(GL10 gl) {
		}

		@Override public String toString() {
		    StringBuilder result = new StringBuilder();
		    result.append("NULL-rail");
		    return result.toString();
		  }

	}

	public static final Rail NULL = new NullRail();


	@Override public String toString() {
	    StringBuilder result = new StringBuilder();
	    result.append(shift+" r"+rotation);
	    return result.toString();
	  }
}
